﻿//
// Copyright (c) 2011 Western Data Solutions (www.westerndatasolutions.com) (Armen Shimoon)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without 
// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 
// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 
// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections.Generic;
using System.IO;
using WDS.Bencode.Fluent;

namespace WDS.Bencode
{   
    /// <summary>
    /// Factory class for creating strongly typed bencoded elements
    /// </summary>
    public static class Bencode
    {
        /// <summary>
        /// A bencoded representation of a string
        /// </summary>
        /// <param name="value">The string value to encode</param>
        /// <returns>A bencoded string</returns>
        public static BencodeString @String(string value)
        {
            return new BencodeString(value);
        }

        /// <summary>
        /// A bencoded representation of an integer
        /// </summary>
        /// <param name="value">The integer value to encode</param>
        /// <returns>A bencoded integer</returns>
        public static BencodeInteger Integer(int value)
        {
            return new BencodeInteger(value);
        }

        /// <summary>
        /// A bencoded representation of a dictionary
        /// </summary>
        /// <param name="elements">A list of bencoded key-value-pairs</param>
        /// <returns></returns>
        public static BencodeDictionary Dictionary(params KeyValuePair<BencodeString,BencodeElement>[] elements)
        {
            var dict = new BencodeDictionary();
            foreach (var keyValuePair in elements)
            {
                dict.Add(keyValuePair.Key, keyValuePair.Value);
            }
            return dict;
        }

        /// <summary>
        /// A bencoded representation of a dictionary using fluent-syntax
        /// </summary>
        /// <returns>A fluent-syntax bencode dictionary builder</returns>
        public static BencodeDictionaryBuilder Dictionary()
        {
            return new BencodeDictionaryBuilder();
        }

        /// <summary>
        /// A bencoded representation of a dictionary key-value-pair
        /// </summary>
        /// <param name="key">Bencoded string key</param>
        /// <param name="value">Any bencoded element</param>
        /// <returns>A key-value-pair</returns>
        public static KeyValuePair<BencodeString,BencodeElement>Pair(BencodeString key, BencodeElement value)
        {
            return new KeyValuePair<BencodeString, BencodeElement>(key, value);
        }

        /// <summary>
        /// A bencoded representation of a list
        /// </summary>
        /// <param name="elements">A list of any bencoded elements</param>
        /// <returns>A bencoded list</returns>
        public static BencodeList List(params BencodeElement[] elements)
        {
            var list = new BencodeList();
            foreach (var bencodeElement in elements)
            {
                list.Add(bencodeElement);
            }
            return list;
        }

        /// <summary>
        /// A bencoded representation of a list using fluent syntax
        /// </summary>
        /// <returns>A fluent-syntax bencode list builder</returns>
        public static BencodeListBuilder List()
        {
            return new BencodeListBuilder();
        }

        public static BencodeElement ReadFromFile(string filePath)
        {
            return new FileStream(filePath, FileMode.Open, FileAccess.Read).ToBencodeElement();
        }

        public static TBencodeElement ReadFromFile<TBencodeElement>(string filePath) where TBencodeElement : BencodeElement
        {
            return ReadFromFile(filePath) as TBencodeElement;
        }
    }
}
